package com.itheima.sevice.impl;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.TemplateExportParams;
import com.itheima.dao.ReportDao;
import com.itheima.pojo.*;
import com.itheima.sevice.ReportService;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.time.LocalDate;
import java.util.*;

@Service
public class ReportServiceImpl implements ReportService {

    @Autowired
    private ReportDao reportDao;

    /**
     * 获取会员统计数据
     * @return
     */
    @Override
    public MemberReportVO getMemberReport() {
        MemberReportVO memberReportVO = new MemberReportVO();
        memberReportVO.setMonths(reportDao.getMemberRegTime());
        memberReportVO.setMemberCount(reportDao.countMemberByRegTime());

        return memberReportVO;
    }

    /**
     * 套餐预约占比饼图
     * @return
     */
    @Override
    public SetmealReportVO getSetmealReport() {
        SetmealReportVO setmealReportVO = new SetmealReportVO();
        List<String> setmealNames = reportDao.getSetmealNames();
        setmealReportVO.setSetmealNames(setmealNames);

        List<SetmealCount> setmealCounts = new ArrayList<>();
        for (String setmealName : setmealNames) {
            Integer value = reportDao.countSetmealBySetmealName(setmealName);
            SetmealCount setmealCount = SetmealCount
                    .builder()
                    .name(setmealName)
                    .value(value)
                    .build();
            setmealCounts.add(setmealCount);
        }
        setmealReportVO.setSetmealCounts(setmealCounts);

        return setmealReportVO;
    }

    /**
     * 运营数据统计
     * @return
     */
    @Override
    public BusinessReportDataVO getBusinessReportData() {
        // 当前日期
        LocalDate today = LocalDate.now();
        // 这周开始日期
        LocalDate beginOfWeek = LocalDate.of(today.getYear(),
                today.getMonth(),
                today.getDayOfMonth()-today.getDayOfWeek().getValue()+1);
        // 这月开始日期
        LocalDate beginOfMonth = LocalDate.of(today.getYear(),
                today.getMonth(),
                LocalDate.MIN.getDayOfMonth());

        // 会员数据统计
        Integer totalMember = reportDao.countTotalMemberByRegTime(null, null);
        Integer todayNewMember = reportDao.countTotalMemberByRegTime(today, today);
        Integer thisWeekNewMember = reportDao.countTotalMemberByRegTime(beginOfWeek, today);
        Integer thisMonthNewMember = reportDao.countTotalMemberByRegTime(beginOfMonth, today);

        // 预约到诊数据统计
        Integer todayOrderNumber = reportDao.countTotalOrderByOrderDate(today, today, null);
        Integer thisWeekOrderNumber = reportDao.countTotalOrderByOrderDate(beginOfWeek, today, null);
        Integer thisMonthOrderNumber = reportDao.countTotalOrderByOrderDate(beginOfMonth, today, null);

        Integer todayVisitsNumber = reportDao.countTotalOrderByOrderDate(today, today, Order.ORDERSTATUS_YES);
        Integer thisWeekVisitsNumber = reportDao.countTotalOrderByOrderDate(beginOfWeek, today, Order.ORDERSTATUS_YES);
        Integer thisMonthVisitsNumber = reportDao.countTotalOrderByOrderDate(beginOfMonth, today, Order.ORDERSTATUS_YES);

        // 热门套餐数据统计
        List<String> setmealNames = reportDao.getSetmealNames();
        Integer totalSetmeal = reportDao.getTotalSetmeal();
        List<SetmealCount> hotSetmeal = new ArrayList<>();
        for (String setmealName : setmealNames) {
            Integer value = reportDao.countSetmealBySetmealName(setmealName);
            SetmealCount setmealCount = SetmealCount
                    .builder()
                    .proportion(1.0 * value / totalSetmeal)
                    .name(setmealName)
                    .value(value)
                    .build();
            hotSetmeal.add(setmealCount);
        }

        return BusinessReportDataVO
                .builder()
                .reportDate(today)
                .totalMember(totalMember)
                .todayNewMember(todayNewMember)
                .thisWeekNewMember(thisWeekNewMember)
                .thisMonthNewMember(thisMonthNewMember)
                .todayOrderNumber(todayOrderNumber)
                .thisWeekOrderNumber(thisWeekOrderNumber)
                .thisMonthOrderNumber(thisMonthOrderNumber)
                .todayVisitsNumber(todayVisitsNumber)
                .thisWeekVisitsNumber(thisWeekVisitsNumber)
                .thisMonthVisitsNumber(thisMonthVisitsNumber)
                .hotSetmeal(hotSetmeal)
                .build();
    }

    /**
     * 导出数据到Excel
     * @param response
     */
    @Override
    public void exportBusinessReport(HttpServletResponse response) throws Exception {
        // 置流文件的编码格式（setHeader、setContentType）
        response.setHeader("content-Disposition", "attachment; filename=report_template.xlsx");
        response.setContentType("application/vnd.ms-excel;charset=gb2312");

        TemplateExportParams params = new TemplateExportParams(
                "templates/report_template.xlsx");
        // 获取报表数据
        BusinessReportDataVO businessReportData = getBusinessReportData();
        Map<String, Object> map = new HashMap<>();
        map.put("reportDate", businessReportData.getReportDate());
        map.put("todayNewMember", businessReportData.getTodayNewMember());
        map.put("totalMember", businessReportData.getTotalMember());
        map.put("thisWeekNewMember", businessReportData.getThisWeekNewMember());
        map.put("thisMonthNewMember", businessReportData.getThisMonthNewMember());
        map.put("todayOrderNumber", businessReportData.getTodayOrderNumber());
        map.put("todayVisitsNumber", businessReportData.getTodayVisitsNumber());
        map.put("thisWeekOrderNumber", businessReportData.getThisWeekOrderNumber());
        map.put("thisWeekVisitsNumber", businessReportData.getThisWeekVisitsNumber());
        map.put("thisMonthOrderNumber", businessReportData.getThisMonthOrderNumber());
        map.put("thisMonthVisitsNumber", businessReportData.getThisMonthVisitsNumber());

        List<Map<String, Object>> listMap = new ArrayList<>();
        for (SetmealCount setmealCount : businessReportData.getHotSetmeal()) {
            Map<String, Object> lm = new HashMap<>();
            lm.put("name", setmealCount.getName());
            lm.put("value", setmealCount.getValue());
            lm.put("proportion", setmealCount.getProportion());

            listMap.add(lm);
        }
        map.put("hotSetmeal", listMap);

        Workbook workbook = ExcelExportUtil.exportExcel(params, map);
        ServletOutputStream fos = response.getOutputStream();
        workbook.write(fos);
        fos.close();
    }
}
